/*
 * stack_description.h
 *
 *  Created on: Mar 12, 2012
 *      Author: qian
 */
#include <stdio.h>
#include "auxiliary.h"

#ifndef STACK_DESCRIPTION_H_
#define STACK_DESCRIPTION_H_

/*SILICON properties are from COMSOL material library, BEOL properties are same as those in 3D-ICE, water thermal conductivity from web,
 * but its specific heat is synchronized with 3D-ICE*/
#define K_BEOL 		2.25 //(W/m-k)
#define K_SILICON 	163 //(W/m-k)
#define K_Fluid		0.58 /*W/(mK)*/
#define K_Liner		30 /*W/(mK)*/
#define T_Liner 0.25e-6 //liner thickness

#define V_POWER		0
#define V_TEMP		1

/* block list: block to grid mapping data structure.
 * list of blocks mapped to a grid cell
 */
typedef struct blist_t_st
{
	/* index of the mapped block	*/
	int idx;
	/* ratio of this block's area within the grid cell
	 * to the total area of the grid cell
	 */
	double occupancy;
	/* next block mapped to the same cell	*/
	struct blist_t_st *next;
}blist_t;

/* grid list: grid to block mapping data structure.
 * start and end indices of grid cells in a block
 * (both in the x and y directions)
 */
typedef struct glist_t_st
{
	/* start index in the y direction	*/
	int i1;
	/* end index in the y direction + 1	*/
	int i2;
	/* start index in the x direction	*/
	int j1;
	/* end index in the x direction + 1	*/
	int j2;
} glist_t;

/* placed functional unit */
typedef struct unit_t_st
{
	char name[STR_SIZE];
	double width;
	double height;
	double leftx;
	double bottomy;
	double power;
}unit_t;

/* floorplan data structure	*/
typedef struct flp_t_st
{
	unit_t *units;
	int n_units;
} flp_t;

typedef struct layer_st
{
	int	idx;
	double BEOL_height;
	double source_height;
	double bulk_height;

	flp_t *flp;

	/* block-grid map - 2-d array of block lists	*/
	blist_t ***b2gmap;
	/* grid-block map - a 1-d array of grid lists	*/
	glist_t *g2bmap;

} layer_t;

/*contains physical information of TSVs*/
typedef struct tsv_physi_st
{
    /*x, y coordinates*/
	double x;
    double y;
    /*starting layer (lower)*/
    int z1;
    /*starting sublayer*/
    int	sl1;
    /*ending layer (higher)*/
    int z2;
    /*ending sublayer*/
    int sl2;
    double width;
}tsv_physi_t;

typedef struct heatsink_st
{
	/*heatsink spec*/
	double t_heatsink;
	double width_heatsink;
	double k_heatsink;
	double r_conv;
	/*spreader spec*/
	double t_spreader;
	double width_spreader;
	double k_spreader;
	/*TIM spec*/
	double t_TIM;
	double k_TIM;
}heatsink_t;

typedef struct microchannel_st
{
	double channel_width;
	double channel_height;
	double wall_width;
	int n_channels_per_layer;
	double default_flowrate;
}microchannel_t;

typedef struct stack_description_st
{
	double 	width;  //chip width
	double 	length; //chip length
	int 	n_layers; //number of layers of circuit
	int		rows;	//grid row number
	int		cols;	//grid column number
	/*cooling method of chip, "1" stands for Heatsink-based cooling, "2" stands for cooling by Microfluidic channels*/
	int		cooling_method;
	/*TSV flag, "0" means doesn't consider TSV, "1" means consider TSV*/
	int		TSV;
	union
	{
		heatsink_t *heatsink;
		microchannel_t *microchannel;
	};

	layer_t *layers;	//layer properties
//	tsv_t *tsv;	//TSV properties
    int 	n_tsvs; //number of thermal tsvs
    double	k_tsv; //material of tsv
    tsv_physi_t *tsv_physi; //TSV properties in physical location
    double 	*tsv_circuitx;
    double 	*tsv_circuity;
    double  *tsv_circuitz;
    double	*tsv_bondx;
    double	*tsv_bondy;
    double	*tsv_bondz;
} stk_descr_t;




/*Construct stack description from layer configuration file and floorplan*/
void build_stack_description(IO_t* IO, stk_descr_t* stk);

/* parse the 3d stack configuration file open for reading	*/
void parse_config_file(stk_descr_t *stk, FILE *fp);

/*parse floorplan files*/
flp_t *read_flp(char *file);

void read_tsv(stk_descr_t *stk, char *file);

/*
 * find the number of units from the
 * floorplan file
 */
int flp_count_units(FILE *fp);

/*allocate memory for floorplan units*/
flp_t *flp_alloc_init_mem(int count);

/* populate block information	*/
void flp_populate_blks(flp_t *flp, FILE *fp);

/* translate the floorplan to new origin (x,y)	*/
void flp_translate(flp_t *flp, double x, double y);

/*obtain die width from floorplan information*/
double get_total_width(flp_t *flp);

/*obtain die length from floorplan information*/
double get_total_length(flp_t *flp);

/*allocate memory for b2gmap*/
blist_t ***new_b2gmap(int rows, int cols);

/* destructor	*/
void delete_b2gmap(blist_t ***b2gmap, int rows, int cols);

/* compute the power/temperature average weighted by occupancies	*/
double blist_avg(blist_t *ptr, flp_t *flp, double *v, int type);

/* re-initialize */
void reset_b2gmap(stk_descr_t *stk);

/* create a linked list node and append it at the end	*/
void blist_append(blist_t *head, int idx, double occupancy);

/* constructors	*/
blist_t *new_blist(int idx, double occupancy);

/* setup the block and grid mapping data structures	*/
void set_bgmap(stk_descr_t *stk);

/*calculate total number of units of the 3D stack*/
int obtain_total_units(stk_descr_t *stk);

/*debug use, print out stack desciption*/
void check_stk_description(stk_descr_t* stk);

void tsv_translate(stk_descr_t* stk);

void init_tsv(stk_descr_t* stk);


#endif /* STACK_DESCRIPTION_H_ */
